package com.neusoft.neuiotms.dcam.fixed.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.transaction.Transactional;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.neusoft.bizcore.web.constant.ExceptionConstants;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.bizcore.web.support.Searchable;
import com.neusoft.neuiotms.dcam.fixed.converter.InventoryResultConverter;
import com.neusoft.neuiotms.dcam.fixed.dto.AssetDTO;
import com.neusoft.neuiotms.dcam.fixed.dto.InventoryResultDTO;
import com.neusoft.neuiotms.dcam.fixed.model.InventoryResult;
import com.neusoft.neuiotms.dcam.fixed.model.enums.InventoryDutyResultStatus;
import com.neusoft.neuiotms.dcam.fixed.repository.InventoryResultRepository;
import com.neusoft.neuiotms.dcam.fixed.service.AssetService;
import com.neusoft.neuiotms.dcam.fixed.service.InventoryResultService;

@Service
public class InventoryResultServiceImpl implements InventoryResultService {

    @Autowired
    private InventoryResultRepository inventoryDutyResultRepository;
    @Autowired
    private InventoryResultConverter inventoryDutyResultConverter;
    @Autowired
    private AssetService assetService;

    @Override
    public List<InventoryResultDTO> findAll(final Searchable searchable) {
        final List<InventoryResult> models = this.inventoryDutyResultRepository.search(searchable);
        return this.inventoryDutyResultConverter.toListDTO(models);
    }

    @Override
    public Page<InventoryResultDTO> search(final Pageable pageable, final Searchable searchable) {
        final Page<InventoryResult> models = this.inventoryDutyResultRepository.search(pageable, searchable);
        return this.inventoryDutyResultConverter.toPageDTO(models);
    }

    @Override
    public InventoryResultDTO create(final InventoryResultDTO dto) {

        InventoryResult model = this.inventoryDutyResultConverter.toModel(dto);
        model = this.inventoryDutyResultRepository.save(model);

        return this.inventoryDutyResultConverter.toDTO(model);
    }

    @Override
    public InventoryResultDTO details(final Long id) {

        final InventoryResult model;
        try {
            model = this.inventoryDutyResultRepository.getOne(id);
        } catch (final Exception e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        return this.inventoryDutyResultConverter.toDTO(model);
    }

    @Override
    public InventoryResultDTO update(final Long id, final InventoryResultDTO dto) {

        InventoryResult model;
        try {
            model = this.inventoryDutyResultRepository.getById(id); // getOne(id);
        } catch (final Exception e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        if ((null != model.getAssetId()) && (dto.getDutyResultStatus() == InventoryDutyResultStatus.gain)) {
            throw new UnitedException("已有资产不能修改状态为盘盈!");
        }

        dto.setId(model.getId());
        model = this.inventoryDutyResultConverter.toModel(dto);

        // 变更
        this.inventoryDutyResultRepository.save(model);

        return this.inventoryDutyResultConverter.toDTO(model);
    }

    @Override
    public void updateStatus(final Long id, final InventoryDutyResultStatus status) {

        InventoryResult model;
        try {
            model = this.inventoryDutyResultRepository.getOne(id);
        } catch (final Exception e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        if ((null != model.getAssetId()) && (status == InventoryDutyResultStatus.gain)) {
            throw new UnitedException("已有资产不能修改状态为盘盈!");
        }

        model.setDutyResultStatus(status);

        this.inventoryDutyResultRepository.save(model);
    }

    @Override
    public void delete(final Long id) {

        InventoryResult model;
        try {
            model = this.inventoryDutyResultRepository.getOne(id);
        } catch (final Exception e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        if (null != model.getAssetId()) {
            throw new UnitedException("只能删除新增的盘盈数据");
        }

        this.inventoryDutyResultRepository.deleteById(id);
    }

    @Override
    @Transactional
    public void synchronousData(final String ids, final String rule) {
        if (StringUtils.isEmpty(rule) || StringUtils.isEmpty(ids)) {
            return;
        }

        final String[] rules = rule.split(",");

        final List<Long> longArray = new ArrayList<>();
        final String[] idArray = ids.split(",");
        Arrays.asList(idArray).forEach(item -> longArray.add(Long.parseLong(item)));

        final Searchable searchable = new Searchable();
        // searchable.put("planId", planId);
        searchable.put("ids", longArray);
        final List<InventoryResultDTO> dtos = this.findAll(searchable);

        dtos.forEach(m -> {

            // 盘盈添加资产
            if (InventoryDutyResultStatus.gain.equals(m.getDutyResultStatus()) &&
                    Arrays.asList(rules).contains("1")) {
                final AssetDTO dto = this.inventoryDutyResultConverter.toDTO(m);
                final AssetDTO assetDTO = this.assetService.create(dto);
                m.setAssetId(assetDTO.getId());
                this.inventoryDutyResultRepository.save(this.inventoryDutyResultConverter.toModel(m));
            }

            // 盘亏删除资产
            else if (InventoryDutyResultStatus.loss.equals(m.getDutyResultStatus()) &&
                    Arrays.asList(rules).contains("3")) {
                if (null != m.getAssetId()) {
                    this.assetService.delete(m.getAssetId());
                }
            }

            // 其他是否修改了信息
            else if (Arrays.asList(rules).contains("2")) {
                if ((null != m.getAssetId())
                        && ((null != m.getUpdateUserId()) || !StringUtils.isEmpty(m.getUpdateOrgCode())
                                || (!StringUtils.isEmpty(m.getUpdateLocationCode())))) {
                    final AssetDTO dto = this.assetService.details(m.getAssetId());

                    // 使用人变更
                    if (null != m.getUpdateUserId()) {
                        dto.setUserId(m.getUpdateUserId());
                        dto.setUserName(m.getUpdateUserName());
                    }

                    // 组织变更
                    if (!StringUtils.isEmpty(m.getUpdateOrgCode())) {
                        dto.setOrgId(m.getUpdateOrgCode());
                        dto.setOrgName(m.getUpdateOrgName());
                    }

                    // 位置变更
                    if (!StringUtils.isEmpty(m.getUpdateLocationCode())) {
                        dto.setLocationCode(m.getUpdateLocationCode());
                        dto.setLocationName(m.getUpdateLocationName());
                    }

                    this.assetService.update(m.getAssetId(), dto);
                }
            }
        });
    }

}
